#
# Copyright 2008 Spencer Davis <SpencerDavis91@gmail.com>
# Copyright 2008 Charles Connell <charles@connells.org>
#
# This file is part of Recuerde.
#
# Recuerde is free software; you can redistribute it and/or
# modify it under the terms of the GNU General Public License
# as published by the Free Software Foundation; either version 2
# of the License, or (at your option) any later version.
# 
# Recuerde is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
# GNU General Public License for more details.
# 
# You should have received a copy of the GNU General Public License
# along with Recuerde; if not, see <http://gnu.org/licenses/.>
#

import os
import sys
import wx
import recuerde
from recuerde import Item
from database import Database

class AddDialog(wx.Dialog):
    """Dialog box to add an item to a list."""
    def __init__(self, itemList, db, parent):
        wx.Dialog.__init__(self, parent, wx.ID_ANY, 'Add Item To List %s - Recuerde' % itemList.name)
        """Creates the dialog box for adding an item."""

        # Remember database for use in OnAdd
        self.db = db

        # Remember list that new item will be added to
        self.itemList = itemList

        # Create list to remember widgets for use in OnAdd
        self.widgetList = []

        # Create sizer to hold widgets
        mainSizer = wx.BoxSizer(wx.VERTICAL)

        # Add label to top of dialog
        mainSizer.Add(wx.StaticText(self, label = 'New Item In List %s' % itemList.name), flag=wx.EXPAND | wx.ALL, border=10)

        # Create text control for entering item name
        self.nameCtrl = wx.TextCtrl(self, size=(500, -1))
        # Create label to accompany name text control and add it to the sizer
        mainSizer.Add (wx.StaticText(self, label='Name'), flag=wx.LEFT, border=10)
        # Add name text control to sizer, push other widgets away except those on top (the label)
        mainSizer.Add (self.nameCtrl, flag=wx.EXPAND | wx.LEFT | wx.RIGHT | wx.BOTTOM, border=10)
        # Bind to handler which will enable Add button when name text control is filled in
        self.nameCtrl.Bind(wx.EVT_TEXT, self.OnListNameChange)
        # Give focus so user can enter name first
        self.nameCtrl.SetFocus()

        # For every field in the list, we need a widget to allow the user to specify a value for it
        for field in self.itemList.GetFields():
            # If field is text, make a text control
            if field[0] is recuerde.FIELDTYPE_STRING:
                widget = wx.TextCtrl(self, size=(500, -1))
            # If field is a date, make a date picker
            elif field[0] is recuerde.FIELDTYPE_DATE:
                widget = wx.DatePickerCtrl(self, size=(500, -1))
            # If field is a choice, make a combobox with the appropriate choices
            elif field[0] is recuerde.FIELDTYPE_CHOICE:
                widget = wx.ComboBox(self, size=(500, -1), style=wx.CB_READONLY, value=field[2][0], choices=field[2])
            # Remember each widget for later
            self.widgetList.append(widget)
            # Add a label with the field's name to the sizer
            mainSizer.Add (wx.StaticText(self, label=field[1]), flag=wx.LEFT, border=10)
            # Add the widget to the sizer just under the label
            mainSizer.Add (widget, flag=wx.EXPAND | wx.LEFT | wx.RIGHT | wx.BOTTOM, border=10)

        # Create label that can display error messages to the user. It is currently empty and therefore invisible.
        self.errorCtrl = wx.StaticText(self)
        # Add that to the sizer under the last field widget
        mainSizer.Add(self.errorCtrl, flag=wx.EXPAND | wx.ALL, border=10)

        # Create sizer to hold this dialog's Add and Cancel buttons. Cancel button comes with the returned sizer.
        buttonSizer = self.CreateButtonSizer(wx.CANCEL)
        # Add an Add button to it, and remember that button for later use in OnListNameChange
        self.addButton = wx.Button(self, wx.ID_ADD)
        # If button is clicked, run OnAdd
        self.addButton.Bind(wx.EVT_BUTTON, self.OnAdd)
        # Add button to sizer
        buttonSizer.Add (self.addButton, flag=wx.EXPAND | wx.LEFT | wx.RIGHT, border=10)
        # Add sizer with Add and Cancel buttons to main widget sizer
        mainSizer.Add(buttonSizer, flag=wx.EXPAND | wx.ALL, border=10)
        # Disable Add button because the name field is currently empty, and you cannot have an item with no name
        self.addButton.Disable()

        # Distribute widgets nicely
        self.SetSizer(mainSizer)
        mainSizer.Fit(self)

    def OnListNameChange(self, event):
        """If name text control has text, allow user to add the item (but not if there is no text)"""
        if self.nameCtrl.GetValue():
            self.addButton.Enable()
        else:
            self.addButton.Disable()

    def OnAdd(self, event):
        """Reads the information from the dialog and saves the item."""
        # Make empty item that will soon be filled with values from the dialog
        i = Item()

        # Find items with a duplicate name in this list
        duplicate = filter(lambda item: item.GetName() == self.nameCtrl.GetValue(), self.itemList.GetItems())

        # If there is a duplicate, tell user through error label and do nothing else
        if (len(duplicate) is not 0):
            self.errorCtrl.SetLabel('There is already an item named "%s" in list "%s", please choose another name.' % (self.nameCtrl.GetValue(), self.itemList.GetName()))

        # Otherwise, proceed
        else:
            # Set the item's name from the name text control
            i.SetName(self.nameCtrl.GetValue())

            # Loop through each widget in the dialog and each field in the list simultaneously
            # Set the values for each field from the widget in the dialog
            for field, widget in zip(self.itemList.GetFields(), self.widgetList):
                i.SetProperty(field[1], widget.GetValue())

            # Write this item to the database, and add it to the in-memory list
            self.db.AddItem(i, self.itemList)

            # Close this dialog
            self.EndModal (wx.ID_ADD)

